package com.abl.domain.model;

import com.abl.common.mybatis.model.Page;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;

import java.util.HashMap;
import java.util.List;

/**
 * SRS 通用对象工具
 * 1.用于返回对象
 * 2.用于创建实体
 */
public class SRS<T> extends HashMap {

    /**
     * 请求状态（true成功/false失败）
     *
     * @mock true
     * @apiNote
     */
    private boolean status;


    /**
     * 状态对应编码（0成功；1失败；其他）
     *
     * @mock 0
     **/
    private String code;


    /**
     * 返回消息（操作成功/操作失败/其他）
     *
     * @mock 操作成功
     */
    private String message;

    /**
     * 请求对应的响应数据
     */
    private T data;

    /**
     * 请求响应时间戳
     */
    private String timestamp;

    public static <T> SRS<T> create() {
        return new SRS<T>();
    }

    public static <T> SRS<T> bySuccess() {
        return bySuccess(AblMsg.SUCCESS_200, new JSONObject());
    }

    public static <T> SRS<T> byError() {
        return byError(AblMsg.ERROR_500, new JSONObject());
    }

    public static <T> SRS<T> byError(String message) {
        return byError().message(message);
    }

    public static <T> SRS<T> bySuccess(Object data) {
        SRS<T> srs = bySuccess(AblMsg.SUCCESS_200, data);
        return setPageData(data, srs);
    }


    public static <T> SRS<T> byError(Object data) {
        SRS<T> srs = byError(AblMsg.SUCCESS_200, data);
        return setPageData(data, srs);
    }

    public static <T> SRS<T> byError(Object data, String message) {
        return byError(AblMsg.ERROR_500, data).message(message);
    }

    public static <T> SRS<T> bySuccess(AblMsg resMsg) {
        return bySuccess(resMsg, new JSONObject());
    }

    public static <T> SRS<T> byError(AblMsg resMsg) {
        return byError(resMsg, new JSONObject());
    }

    public static <T> SRS<T> bySuccess(AblMsg resMsg, Object data) {
        return create()
                .code(resMsg.getCode())
                .message(resMsg.getMessage())
                .status(resMsg.getStatus())
                .data(data);
    }

    public static <T> SRS<T> byError(AblMsg resMsg, Object data) {
        return create()
                .code(resMsg.getCode())
                .message(resMsg.getMessage())
                .status(resMsg.getStatus())
                .data(data);
    }

    public <T> SRS<T> data(Object data) {
        return this.set("data", data);
    }

    public <T> SRS<T> status(boolean status) {
        return this.set("status", status);
    }

    public <T> SRS<T> message(Object message) {
        return this.set("message", message);
    }

    public <T> SRS<T> code(int code) {
        return this.set("code", code);
    }

    public static <T> SRS<T> create(String type, Object value) {
        return create().set(type, value);
    }

    private static <T> SRS<T> setPageData(Object data, SRS srs) {
        if (data instanceof Page) {
            srs.set("total", ((Page) data).getTotal());
            srs.set("size", ((Page) data).getSize());
            srs.set("current", ((Page) data).getCurrent());
            srs.set("pages", ((Page) data).getPages());
            srs.set("isFirst", ((Page) data).isFirst());
            srs.set("isLast", ((Page) data).isLast());
            srs.set("data", ((Page) data).getData());
        }
        return srs;
    }

    /**
     * 复制对象并重新开辟内存空间
     */
    public static JSONObject copyObj(Object object) {
        return JSON.parseObject(JSON.toJSONString(object));
    }

    /**
     * 复制对象并重新开辟内存空间
     */
    public static JSONArray copyArray(Object arrayObject) {
        return JSON.parseArray(JSON.toJSONString(arrayObject));
    }

    /**
     * 复制对象并重新开辟内存空间
     */
    public SRS copy() {
        return JSON.parseObject(this.toString(), SRS.class);
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }

    public static JSONObject parseObj(Object obj) {
        return JSON.parseObject(JSON.toJSONString(obj));
    }

    public <T> T parse(Class<T> c) {
        return JSON.parseObject(JSON.toJSONString(this), c);
    }

    public <T> List<T> parseArray(Class<T> c) {
        return JSON.parseArray(JSON.toJSONString(this), c);
    }

    public SRS set(String type, Object value) {
        super.put(type, value);
        return this;
    }

    private static String toJsonStringNull(Object o) {
        return JSON.toJSONString(o, JSONWriter.Feature.WriteMapNullValue);
    }
}
